﻿using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;

namespace FileTransferDesktop.Models;

public static class CollectionViewExtensions
{
    public static CollectionView<T> Cast<T>(this ICollectionView original)
    {
        return new CollectionView<T>(original);
    }
}

public class CollectionView<T>(ICollectionView original) : ICollectionView, IEnumerable<T>
{
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        foreach (var item in original)
        {
            if (item is T tItem)
            {
                yield return tItem;
            }
            else
            {
                throw new InvalidCastException(
                    $"Item of type {item.GetType()} cannot be cast to {typeof(T)}."
                );
            }
        }
    }

    public IEnumerator GetEnumerator() => original.GetEnumerator();

    public event NotifyCollectionChangedEventHandler? CollectionChanged
    {
        add => original.CollectionChanged += value;
        remove => original.CollectionChanged -= value;
    }

    public bool Contains(object item) => original.Contains(item);

    public IDisposable DeferRefresh() => original.DeferRefresh();

    public bool MoveCurrentTo(object item) => original.MoveCurrentTo(item);

    public bool MoveCurrentToFirst() => original.MoveCurrentToFirst();

    public bool MoveCurrentToLast() => original.MoveCurrentToLast();

    public bool MoveCurrentToNext() => original.MoveCurrentToNext();

    public bool MoveCurrentToPosition(int position) => original.MoveCurrentToPosition(position);

    public bool MoveCurrentToPrevious() => original.MoveCurrentToPrevious();

    public void Refresh() => original.Refresh();

    public bool CanFilter => original.CanFilter;

    public bool CanGroup => original.CanGroup;

    public bool CanSort => original.CanSort;

    public CultureInfo Culture
    {
        get => original.Culture;
        set => original.Culture = value;
    }

    public object CurrentItem => original.CurrentItem;

    public int CurrentPosition => original.CurrentPosition;

    public Predicate<object> Filter
    {
        get => original.Filter;
        set => original.Filter = value;
    }

    public ObservableCollection<GroupDescription> GroupDescriptions => original.GroupDescriptions;
    public ReadOnlyObservableCollection<object> Groups => original.Groups;
    public bool IsCurrentAfterLast => original.IsCurrentAfterLast;
    public bool IsCurrentBeforeFirst => original.IsCurrentBeforeFirst;
    public bool IsEmpty => original.IsEmpty;
    public SortDescriptionCollection SortDescriptions => original.SortDescriptions;
    public IEnumerable SourceCollection => original.SourceCollection;
    public event EventHandler? CurrentChanged
    {
        add => original.CurrentChanged += value;
        remove => original.CurrentChanged -= value;
    }
    public event CurrentChangingEventHandler? CurrentChanging
    {
        add => original.CurrentChanging += value;
        remove => original.CurrentChanging -= value;
    }
}
